用objection大致了看下,
1.1 查看有哪些类
1
android hooking search classes com.example.seccon2015
返回结果,发现比较简单,就一个类:
1
2
3com.example.seccon2015.rock_paper_scissors.MainActivity
com.example.seccon2015.rock_paper_scissors.MainActivity$1
Found 2 classes1.2 查看有该类中有哪些方法
1
2
3
4
5
6
7
8seccon2015.rock_paper_scissors on (google: 7.1.2) [usb] # android hooking list class_methods com.example.seccon2015.rock_paper_scissors.MainActivity
# 返回结果
protected void com.example.seccon2015.rock_paper_scissors.MainActivity.onCreate(android.os.Bundle)
public native int com.example.seccon2015.rock_paper_scissors.MainActivity.calc()
public void com.example.seccon2015.rock_paper_scissors.MainActivity.onClick(android.view.View)
Found 3 method(s)发现仅3个方法,其中有一个native方法,
实现方法
oncreate方法,声明了button控件以及对应的监听器
1
2
3
4
5
6
7
8
9
10
11public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.P = (Button) findViewById(R.id.button);
this.S = (Button) findViewById(R.id.button3);
this.r = (Button) findViewById(R.id.buttonR);
this.P.setOnClickListener(this);
this.r.setOnClickListener(this);
this.S.setOnClickListener(this);
this.flag = 0;
}onClick方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29public void onClick(View v) {
if (this.flag != 1) {
this.flag = 1;
((TextView) findViewById(R.id.textView3)).setText("");
TextView tv = (TextView) findViewById(R.id.textView);
this.m = 0; //玩家
// 设置n为随机数0,1,2
this.n = new Random().nextInt(3); //PC
// 随机出 布/石头/剪刀
((TextView) findViewById(R.id.textView2)).setText(new String[]{"CPU: Paper", "CPU: Rock", "CPU: Scissors"}[this.n]);
// 如果玩家出布,m置为0
if (v == this.P) {
tv.setText("YOU: Paper");
this.m = 0;
}
// 如果玩家出石头,m置为1
if (v == this.r) {
tv.setText("YOU: Rock");
this.m = 1;
}
// 如果玩家出剪刀,m置为2
if (v == this.S) {
tv.setText("YOU: Scissors");
this.m = 2;
}
// 执行定时任务
this.handler.postDelayed(this.showMessageTask, 1000);
}
}继续查看showMessageTask方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30private final Runnable showMessageTask = new Runnable() {
public void run() {
TextView tv3 = (TextView) MainActivity.this.findViewById(R.id.textView3);
// 如果玩家win
if (MainActivity.this.n - MainActivity.this.m == 1) {
MainActivity.this.cnt++;
tv3.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
// 如果玩家lose
} else if (MainActivity.this.m - MainActivity.this.n == 1) {
MainActivity.this.cnt = 0;
tv3.setText("LOSE +0");
// 如果平局
} else if (MainActivity.this.m == MainActivity.this.n) {
tv3.setText("DRAW +" + String.valueOf(MainActivity.this.cnt));
// 如果玩家lose
} else if (MainActivity.this.m < MainActivity.this.n) {
MainActivity.this.cnt = 0;
tv3.setText("LOSE +0");
// 如果玩家win
} else {
MainActivity.this.cnt++;
tv3.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
}
// 如果连胜1000次,弹出flag
if (1000 == MainActivity.this.cnt) {
tv3.setText("SECCON{" + String.valueOf((MainActivity.this.cnt + MainActivity.this.calc()) * 107) + "}");
}
MainActivity.this.flag = 0;
}
};分析得到flag思路
- 修改返回值为1000,得到flag;
- hook到calc的返回值,得到flag;
- 看到弹出flag的语句,直接想到去分析native的calc方法,得到flag。
方法一:
修改返回值为1000,再点击按钮时,触发点击事件,可能会win,也可能会lose,此时对玩家和pc的值也控制一下,为相同的值,使得分不变。
1 | function hook2() { |
执行结果如下,发现cnt已经修改为1000,同时将flag显示在界面中。
1 | message: {'type': 'send', 'payload': 'hook start--->'} data: None |
方法二:
calc方法在MainActivity类中,直接引用该类下的calc()方法。
1 | function hook1(){ |
执行结果
1 | [Nexus 5X::com.example.seccon2015.rock_paper_scissors]-> |
方法三:
把so文件拉到反编译工具查看其算法,发现就简单的返回一个值,
那就简单多了,直接计算“{SECCON”+1007*107+“}”,得最终flag.